/**
 * 
 */
package cn.com.xf.web.filter;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.CollectionUtils;

import cn.com.xf.common.Constants;
import cn.com.xf.web.XFContainsTool;

/**
 * @author Administrator
 * 
 */
public class AuthoritiesFilter implements Filter {
	Log log = LogFactory.getLog(AuthoritiesFilter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		List<GrantedAuthority> newAuthoritys = getAuthority(auth.getName());
		if (!CollectionUtils.isEmpty(newAuthoritys)) {
			// 增加考勤管理的权限，抽象化
			boolean hasCheckManage = false;
			boolean hasHumenCarline = false;
			boolean hasShenzhenCarline = false;
			for (GrantedAuthority g : newAuthoritys) {
				if (g.getAuthority().startsWith("MANAGE_CHECK_")) {
					hasCheckManage = true;
				}
				if (g.getAuthority().equals("MANAGE_CHECK_HUMEN")) {
					hasHumenCarline = true;
				}
				if (g.getAuthority().equals("MANAGE_CHECK_SHENZHEN")) {
					hasShenzhenCarline = true;
				}
			}
			if (hasCheckManage) {
				newAuthoritys.add(new GrantedAuthorityImpl("MANAGE_CHECK"));
			}
			if (hasHumenCarline) {
				newAuthoritys.addAll(humenCarline());
			}
			if (hasShenzhenCarline) {
				newAuthoritys.addAll(shenzhenCarline());
			}
			UsernamePasswordAuthenticationToken overwrittenToken = new UsernamePasswordAuthenticationToken(
					auth.getPrincipal(), auth.getCredentials(), newAuthoritys);
			SecurityContextHolder.getContext().setAuthentication(overwrittenToken);
		}
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {

	}

	private List<GrantedAuthority> getAuthority(String username) {
		DataSource dateSourceOracle = (DataSource) XFContainsTool.lookup("dateSourceOracle");
		JdbcTemplate temp = new JdbcTemplate(dateSourceOracle);
		String authoritiesByUsernameQuery = "select a.username,p.PERMISSION_TAG "
				+ "from tbl_oa_auth_user_role ar join tbl_oa_auth_user a on "
				+ "ar.BIZ_ID=a.BIZ_ID join tbl_oa_auth_role r on ar.ROLE_ID=r.ROLE_ID "
				+ "join tbl_oa_auth_role_permission rp on rp.ROLE_ID = r.ROLE_ID "
				+ "join tbl_oa_auth_permission p on p.PERMISSION_ID = rp.PERMISSION_ID " + "where a.username=?";

		List<GrantedAuthority> authList = temp.query(authoritiesByUsernameQuery, new String[] { username },
				new RowMapper<GrantedAuthority>() {
					@Override
					public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
						String roleName = Constants.SECURITY_ROLE_PREFIX + rs.getString(2);
						GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
						return authority;
					}
				});
		/*
		 * if (CollectionUtils.isEmpty(authList)) { List<GrantedAuthority>
		 * lowAuthList = new ArrayList<GrantedAuthority>(); GrantedAuthorityImpl
		 * authority_readNotice = new GrantedAuthorityImpl("READ_NOTICE");
		 * GrantedAuthorityImpl authority_readSoft = new
		 * GrantedAuthorityImpl("READ_SOFT"); GrantedAuthorityImpl
		 * authority_readFaq = new GrantedAuthorityImpl("READ_FAQ");
		 * lowAuthList.add(authority_readFaq);
		 * lowAuthList.add(authority_readSoft);
		 * lowAuthList.add(authority_readNotice); return lowAuthList; }
		 */
		return authList;
	}
	
	private List<GrantedAuthority> humenCarline() {
		List<GrantedAuthority> list = new ArrayList<>();
		for (int i = 0; i < Constants.HUMEN_CARLINE.length; i++) {
			GrantedAuthorityImpl authority = new GrantedAuthorityImpl("MANAGE_CHECK_" + Constants.HUMEN_CARLINE[i]);
			list.add(authority);
		}
		return list;
	}
	
	private List<GrantedAuthority> shenzhenCarline() {
		List<GrantedAuthority> list = new ArrayList<>();
		for (int i = 0; i < Constants.SHENZHEN_CARLINE.length; i++) {
			GrantedAuthorityImpl authority = new GrantedAuthorityImpl("MANAGE_CHECK_" + Constants.SHENZHEN_CARLINE[i]);
			list.add(authority);
		}
		return list;
	}

}
